<template>
  <div class="home_child_container">
    <a-back-top/>
    <!-- 左侧卡片 -->
    <a-card class="blog_container_left" :loading="loading">
      <!-- 作者信息 -->
      <div class="author_info">
        <div class="author_info_header">
          关于作者
        </div>
        <div class="author_info_content">
          <router-link :to="`/u/${author.domain}`">
            <a-avatar class="author_avatar" :size="70" :src="author.avatar"/>
          </router-link>
          <div class="author_basic">
            <span class="author_name">{{ author.name }}</span>
            <user-operation :user-id="author.id" :is-owner="author.isOwner" :is-follow="author.isFollow"
                            size="small"/>
          </div>
        </div>
      </div>
      <!-- 目录 -->
      <markdown-anchor-toc/>
    </a-card>
    <!-- 右侧卡片 -->
    <a-card class="blog_container_right" :loading="loading">
      <div class="blog_content">
        <div class="title">{{ blog.title }}</div>
        <!-- 博客信息 -->
        <a-space class="info">
          <a-space class="info_time_item">
            <CalendarOutlined/>
            <span>创建时间:</span>
            <span>{{ blog.createdTime }}</span>
            <a-divider type="vertical"/>
          </a-space>
          <a-space v-if="blog.updatedTime" class="info_time_item">
            <CarryOutOutlined/>
            <span>更新时间:</span>
            <span>{{ blog.updatedTime }}</span>
            <a-divider type="vertical"/>
          </a-space>
          <a-space v-if="blog.classificationName">
            <FolderOutlined/>
            <span>分类:</span>
            <div class="classification_name">{{ blog.classificationName }}</div>
            <a-divider type="vertical"/>
          </a-space>
          <a-space>
            <LikeOutlined/>
            <span>{{ blog.likes }}</span>
            <a-divider type="vertical"/>
          </a-space>
          <a-space>
            <EyeOutlined/>
            <span>{{ blog.pageViews }}</span>
          </a-space>
          <a-space>
            <a-divider type="vertical"/>
            <a @click="openShareModal">分享
              <ShareAltOutlined/>
            </a>
          </a-space>
        </a-space>
        <!-- 博客标签 -->
        <a-space class="tag_list">
          <a-space class="tag" :size="4" v-for="(tag,index) in blog.tagList" :key="index">
            <TagOutlined/>
            <span>{{ tag.name }}</span>
          </a-space>
        </a-space>
        <!-- 博客操作 -->
        <a-space class="author_operation">
          <a-space v-if="blog.isAuthor">
            <router-link :to="`/blog/edit?id=${blogId}`">
              <a-space>
                <span>编辑</span>
                <edit-outlined/>
              </a-space>
            </router-link>
            <a-divider type="vertical"/>
            <a-popconfirm placement="bottomRight" title="确认删除这篇博客？" @confirm="deleteBlog">
              <template #icon>
                <question-circle-outlined style="color: red"/>
              </template>
              <a>
                <a-space>
                  <span>删除</span>
                  <delete-outlined/>
                </a-space>
              </a>
            </a-popconfirm>
            <a-divider type="vertical"/>
            <a @click="exportMarkdown">
              <a-space>
                <span>导出</span>
                <export-outlined/>
              </a-space>
            </a>
          </a-space>
        </a-space>
        <!-- 正文 -->
        <div class="content">
          <markdown :content='`[TOC]\n${blog.content}`'/>
        </div>
        <!-- 操作 -->
        <a-spin :spinning="likeLoading">
          <div class="blog_operation">
            <div class="blog_operation_item" @click="changeLike" v-if="!blog.isLike">
              <LikeOutlined/>
              <span class="blog_operation_item_text">点个赞吧~</span>
            </div>
            <div class="blog_operation_item" @click="changeLike" v-else>
              <LikeFilled/>
              <span class="blog_operation_item_text">感谢点赞~</span>
            </div>
          </div>
        </a-spin>
        <a-divider/>
        <!-- 评论 -->
        <div class="comment">
          <comment-form :key="commentFormKey" :blog-id="blogId" @addComment="addComment"/>
          <a-list item-layout="horizontal" :data-source="commentList" v-if="commentList.length>0">
            <template #renderItem="{ item }">
              <a-list-item :key="item.id">
                <comment :key="item.id" :comment="item" @deleteComment="deleteComment"/>
              </a-list-item>
            </template>
            <template #loadMore>
              <div class="list_load_more_div" v-if="commentList.length > 0">
                <a @click="getMoreComment" v-if="commentHasMore && !commentLoading">加载更多评论</a>
                <a-skeleton v-if="commentLoading" active/>
                <span v-if="!commentHasMore">已加载全部评论！</span>
              </div>
            </template>
          </a-list>
        </div>
      </div>
    </a-card>
    <a-modal v-model:visible="share.visible" :title="`分享博客【${blog.title}】`" ok-text="点击复制链接" :width="500"
             @ok="copyUrl" forceRender>
      <div id="qrcode"></div>
    </a-modal>
  </div>
</template>

<script>
import { computed, defineComponent, getCurrentInstance, onMounted, reactive, toRefs } from 'vue'
import Markdown from '@/components/markdown/Markdown'
import CommentForm from '@/components/comment/CommentForm'
import Comment from '@/components/comment/Comment'
import UserOperation from '@/components/operation/UserOperation'
import {
  CalendarOutlined,
  CarryOutOutlined,
  DeleteOutlined,
  EditOutlined,
  ExportOutlined,
  EyeOutlined,
  FolderOutlined,
  LikeFilled,
  LikeOutlined,
  QuestionCircleOutlined,
  ShareAltOutlined,
  TagOutlined
} from '@ant-design/icons-vue'
import { useRoute, useRouter } from 'vue-router'
import { DeleteBlogForUser, DeleteCommentForUser, GetBlogDetail, GetCommentList, ViewBlog } from '@/service/blog'
import { GetBriefUserById } from '@/service/user'
import { LikeBlog, UnlikeBlog } from '@/service/operate'
import MarkdownAnchorToc from '@/components/blog/MarkdownAnchorToc'
import { qrcanvas } from 'qrcanvas'

export default defineComponent({
  setup () {
    const { proxy } = getCurrentInstance()
    const route = useRoute()
    const router = useRouter()
    const state = reactive({
      blogId: route.params.id,
      loading: true,
      blog: {
        id: '',
        authorId: '',
        title: '',
        content: '',
        classificationId: '',
        classificationName: '',
        tagList: [],
        likes: 0,
        pageViews: 0,
        createdTime: '',
        updatedTime: '',
        isLike: false,
        isAuthor: false
      },
      author: {
        id: '',
        name: '',
        domain: '',
        avatar: '',
        isOwner: false,
        isFollow: false
      },
      likeLoading: false,
      commentList: [],
      commentLoading: false,
      commentHasMore: true,
      commentFormKey: 0,
      share: {
        visible: false,
        url: computed(() => window.document.location.href)
      }
    })

    const methods = reactive({
      deleteBlog: async () => {
        await DeleteBlogForUser(state.blogId)
        proxy.$message.success(`删除博客[${state.blog.title}]成功！`)
        await router.push('/home')
      },
      openShareModal: () => {
        const code = qrcanvas({
          data: state.share.url,
          size: 240
        })
        document.getElementById('qrcode').innerHTML = ''
        document.getElementById('qrcode').appendChild(code)
        state.share.visible = true
      },
      copyUrl: () => {
        const tempInput = document.createElement('input')
        tempInput.value = `${state.share.url} <<${state.blog.title}>>`
        document.body.appendChild(tempInput)
        tempInput.select()
        document.execCommand('copy')
        document.body.removeChild(tempInput)
        proxy.$message.success('复制博客链接成功！')
      },
      exportMarkdown: async () => {
        const element = document.createElement('a')
        element.download = state.blog.title.trim() === '' ? '无标题.md' : state.blog.title.trim() + '.md'
        element.style.display = 'none'
        const blob = new Blob([state.blog.content])
        element.href = URL.createObjectURL(blob)
        document.body.appendChild(element)
        element.click()
        document.body.removeChild(element)
      },
      changeLike: async () => {
        state.likeLoading = true
        if (state.blog.isLike) {
          await UnlikeBlog(state.blogId)
          state.blog.likes -= 1
        } else {
          await LikeBlog(state.blogId)
          state.blog.likes += 1
        }
        state.blog.isLike = !state.blog.isLike
        state.likeLoading = false
      },
      addComment: (comment) => {
        state.commentList.unshift(comment)
        state.commentFormKey++
      },
      deleteComment: async (comment) => {
        await DeleteCommentForUser(comment.id)
        const index = state.commentList.indexOf(comment)
        state.commentList.splice(index, 1)
        proxy.$message.success('删除评论成功！')
      },
      getMoreComment: async () => {
        state.commentLoading = true
        const moreList = state.commentList.length > 0 ? await GetCommentList(state.blogId, state.commentList[state.commentList.length - 1].createdTime) : await GetCommentList(state.blogId)
        if (moreList && moreList.length < 10) {
          state.commentHasMore = false
        }
        state.commentList = state.commentList.concat(moreList)
        state.commentLoading = false
      }
    })

    onMounted(async () => {
      // 增加阅读量
      await ViewBlog(state.blogId)
      // 查询博客信息
      state.blog = await GetBlogDetail(state.blogId)
      // 查询作者信息
      state.author = await GetBriefUserById(state.blog.authorId)
      // 查询评论
      await methods.getMoreComment()
      // 加载完成
      state.loading = false
    })

    return {
      ...toRefs(state),
      ...toRefs(methods)
    }
  },
  components: {
    MarkdownAnchorToc,
    Markdown,
    Comment,
    CommentForm,
    UserOperation,
    CalendarOutlined,
    CarryOutOutlined,
    FolderOutlined,
    TagOutlined,
    LikeOutlined,
    LikeFilled,
    EyeOutlined,
    QuestionCircleOutlined,
    ShareAltOutlined,
    DeleteOutlined,
    EditOutlined,
    ExportOutlined
  }
})
</script>

<style lang="less">
@info-width: 300px;

.home_child_container {

  & .blog_container_left {
    width: @info-width;

    & .author_info {
      width: 100%;
      border-bottom: 1px solid #00000020;
      display: flex;
      flex-direction: column;

      & .author_info_header {
        font-size: 18px;
        font-weight: 700;
        padding-bottom: 15px;
        border-bottom: 1px solid #00000020;
        display: flex;
        justify-content: center;
      }

      & .author_info_content {
        width: 100%;
        height: 120px;
        padding: 5px 0;
        display: flex;
        align-items: center;
        justify-content: center;

        & .author_avatar {
          margin: 5px;
          height: 100%;
          display: flex;
          align-items: center;
        }

        & .author_basic {
          width: 55%;
          margin-left: 10px;
          display: flex;
          flex-direction: column;

          & .author_name {
            font-size: 18px;
            font-weight: 700;
          }
        }
      }
    }
  }

  & .blog_container_right {
    width: calc(100% - @info-width - 10px);

    & .blog_content {
      width: 100%;
      padding: 20px;
      display: flex;
      align-items: center;
      flex-direction: column;

      & .title {
        width: 100%;
        font-size: 30px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        text-align: center;
      }

      & .info {
        margin-top: 20px;
        color: #00000080;

        & .classification_name {
          max-width: 200px;
          color: #00000080;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
      }

      & .tag_list {
        margin-top: 10px;
        display: flex;
        color: #00000080;

        & .tag {
          background-color: #00000015;
          border-radius: 3px;
          font-size: 14px;
          padding: 3px;
        }
      }

      & .author_operation {
        margin: 10px 0;
      }

      & .content {
        margin: 50px 0;
        width: 100%;
        height: 100%;
      }

      & .blog_operation {
        font-size: 25px;
        color: #00000090;
        transition: all 0.5s;

        & .blog_operation_item {
          padding: 10px 15px;
          border-radius: 5px;
          background-color: #00000005;
          cursor: pointer;
          display: flex;
          flex-direction: column;

          &:hover {
            transform: scale(1.1);
          }

          & .blog_operation_item_text {
            font-size: 12px;
            font-weight: 700;
          }
        }
      }

      & .comment {
        width: 100%;
        height: 100%;

        & .ant-list {
          margin: 10px 0;
        }

        & .create_comment_button {
          margin-top: 10px;
          float: right;
        }

        & .list_load_more_div {
          margin-top: 15px;
          width: 100%;
          color: #00000080;
          display: flex;
          justify-content: center;
        }
      }
    }
  }
}

#qrcode {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

@media screen and (max-width: 1400px) {
  .home_child_container {
    & .blog_container_left {
      display: none;
    }

    & .blog_container_right {
      min-width: 100%;

      & .ant-card-body {
        padding: 0;
      }

      & .info {
        flex-wrap: wrap;

        & .info_time_item {
          display: none;
        }

        & .ant-space-item {
          white-space: nowrap;
        }
      }
    }
  }
}
</style>
